﻿using System;

namespace SQLPXBase.Factory.Keys.KeyModels
{
    public class QuadrupledPK<T1, T2, T3, T4> : PrimaryKey
        where T1 : struct
        where T2 : struct
        where T3 : struct 
        where T4:struct
    {
        protected T1? k1;
        protected T2? k2;
        protected T3? k3;
        protected T4? k4;

        #region Constructors

        public QuadrupledPK()
        {
        }

        public QuadrupledPK(T1? k1, T2? k2, T3? k3, T4? k4)
            : this()
        {
            this.k1 = k1;
            this.k2 = k2;
            this.k3 = k3;
            this.k4 = k4;
        }

        #endregion

        public override bool IsEmpty
        {
            get { return !(k1.HasValue || k2.HasValue || k3.HasValue || k4.HasValue); }
        }

        public override PrimaryKey DefaultValue
        {
            get { return new QuadrupledPK<T1, T2, T3, T4>(); }
        }

        public override object GetSingleValue
        {
            get { throw new NotImplementedException(); }
        }

        public override object[] GetValues
        {
            get { return IsEmpty ? null : new object[] { k1, k2, k3, k4 }; }
        }

        public override void SetValues(object[] values)
        {
            CheckValues(values);

            try
            {
                k1 = (T1)values[0];
                k2 = (T2)values[1];
                k3 = (T3) values[2];
                k4 = (T4) values[3];
            }
            catch (Exception ex)
            {
                throw new PrimaryKeyException(ex.Message, ex);
            }
        }

        public override int KeyLength
        {
            get { return 4; }
        }

        public T1? Value1
        {
            get { return k1; }
        }
        public T2? Value2
        {
            get { return k2; }
        }
        public T3? Value3
        {
            get { return k3; }
        }
        public T4? Value4
        {
            get { return k4; }
        }

        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;

            if (obj.GetType() == this.GetType())
            {
                QuadrupledPK<T1, T2, T3, T4> tmp = (QuadrupledPK<T1, T2, T3, T4>) obj;

                if (tmp.IsEmpty && this.IsEmpty)
                    return true;

                if (Equals(tmp.Value1, this.Value1) 
                    && Equals(tmp.Value2, this.Value2)
                    && Equals(tmp.Value3, this.Value3)
                    && Equals(tmp.Value4, this.Value4)
                    )
                    return true;
            }

            return false;
        }
    }
}
